package com.awesome.spring.config;

import io.seata.saga.engine.config.DbStateMachineConfig;
import io.seata.saga.engine.impl.ProcessCtrlStateMachineEngine;
import io.seata.saga.rm.StateMachineEngineHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import javax.sql.DataSource;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * StateMachineEngineConfig
 *
 * @author alex wu
 * @date 2023/10/23
 */
@Configuration
public class StateMachineEngineConfig {

    @Autowired
    private DataSource dataSource;

    @Bean
    public ThreadPoolExecutor threadExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //核心线程数
        executor.setCorePoolSize(1);
        //最大线程数
        executor.setMaxPoolSize(20);
        //线程池中线程的名称前缀
        executor.setThreadNamePrefix("SAGA_ASYNC_EXE_");
        //初始化
        executor.initialize();
        return executor.getThreadPoolExecutor();
    }

    @Bean
    public DbStateMachineConfig dbStateMachineConfig() {
        DbStateMachineConfig stateMachineConfig = new DbStateMachineConfig();
        //设置saga状态机json文件路径
        stateMachineConfig.setDataSource(dataSource);
        ClassPathResource resource = new ClassPathResource("seata/saga_order.json");
        stateMachineConfig.setResources(new Resource[]{resource});
        stateMachineConfig.setEnableAsync(true);
        stateMachineConfig.setThreadPoolExecutor(threadExecutor());
        //seata server服务名
        stateMachineConfig.setApplicationId("seata-server");
        //事物分组
        stateMachineConfig.setTxServiceGroup("seata-saga-account-learn-seata-service-group");
        return stateMachineConfig;
    }

    @Bean
    public ProcessCtrlStateMachineEngine stateMachineEngine() {
        ProcessCtrlStateMachineEngine processCtrlStateMachineEngine = new ProcessCtrlStateMachineEngine();
        processCtrlStateMachineEngine.setStateMachineConfig(dbStateMachineConfig());
        return processCtrlStateMachineEngine;
    }

    @Bean
    public StateMachineEngineHolder stateMachineEngineHolder() {
        StateMachineEngineHolder engineHolder = new StateMachineEngineHolder();
        engineHolder.setStateMachineEngine(stateMachineEngine());
        return engineHolder;
    }
}
